-module(xengine_json).
-export([encode/1]).




-include("xengine.hrl").

encode(Pid)when is_pid(Pid)->
        mochijson2:encode(  io_lib:format("~p",[Pid] ) );
        
encode(Instance) when is_record(Instance,instance)->
       mochijson2:encode( { struct , [{container_name , list_to_binary(Instance#instance.container_name)},
                                       {app_name , list_to_binary(Instance#instance.app_name)}
                                       ]});   
        
encode(App) when is_record(App,app)->
       mochijson2:encode( { struct , [{name , list_to_binary(App#app.name)},
                                       {domain , list_to_binary(App#app.domain)},
                                       {source ,   list_to_binary(App#app.source)} ,
                                       {target  ,list_to_binary(App#app.target)}
                                       ]});   
encode(Container) when is_record(Container,container) ->
        mochijson2:encode( { struct , [{name , list_to_binary(Container#container.name)},
                                       {host , list_to_binary(Container#container.host)},
                                       {ip ,   list_to_binary(Container#container.ip)} ,
                                       {port  ,list_to_binary(Container#container.port)},
                                       {type , list_to_binary(Container#container.type)},
                                       {home, list_to_binary(Container#container.home)}
                                       ]}); 
encode(Runtime) when is_record(Runtime,runtime)->
        mochijson2:encode({struct , [ {cpu , Runtime#runtime.cpu},
                                      {mem , Runtime#runtime.mem},
                                      {up ,   Runtime#runtime.up} ,
                                      {down ,   Runtime#runtime.down} ] });
encode(AccRuntime) when is_record(AccRuntime,acc_runtime)->
        mochijson2:encode({struct , [ {cpu , AccRuntime#acc_runtime.cpu},
                                      {up ,   AccRuntime#acc_runtime.up} ,
                                      {down ,   AccRuntime#acc_runtime.down},
                                      {pv , AccRuntime#acc_runtime.pv} ] });
encode(TotalRuntime) when is_record(TotalRuntime,total_runtime)->
        mochijson2:encode({struct , [ {cpu_time , TotalRuntime#total_runtime.cpu_time},
                                      {up ,   TotalRuntime#total_runtime.up} ,
                                      {down ,   TotalRuntime#total_runtime.down},
                                      {pv , TotalRuntime#total_runtime.pv} ] });
%%encode(AppTotalRuntime) when is_record(AppTotalRuntime,app_total_runtime)->
%%        mochijson2:encode({struct , [ {app ,  list_to_binary(AppTotalRuntime#app_total_runtime.app)},
%%                                      {total_runtime ,  list_to_binary(encode
%%                                              (AppTotalRuntime#app_total_runtime.total_runtime))}] });
                                      
encode(TermRuntime) when is_record(TermRuntime,term_runtime)->
        mochijson2:encode({struct , [ {cpu_time , TermRuntime#term_runtime.cpu_time},
                                      {up ,   TermRuntime#term_runtime.up} ,
                                      {down ,   TermRuntime#term_runtime.down},
                                      {pv , TermRuntime#term_runtime.pv} ] });    
%%encode(AppTermRuntime) when is_record(AppTermRuntime,app_term_runtime)->
%%        mochijson2:encode({struct , [ {app ,  list_to_binary(AppTermRuntime#app_term_runtime.app)},
%%                                       {term_runtime ,  
%%                                                list_to_binary(encode(AppTermRuntime#app_term_runtime.term_runtime))}] });
                                                                                                              
encode(InstanceRuntime) when is_record(InstanceRuntime,instance_runtime)->
        mochijson2:encode({struct , [ {instance ,  list_to_binary(encode( InstanceRuntime#instance_runtime.instance))},
                                      {runtime ,   list_to_binary(encode(InstanceRuntime#instance_runtime.runtime))}
                                        ] });                                      
encode(ContainerRuntime) when is_record(ContainerRuntime,container_runtime)->
%%        error_logger:info_msg("ContainerRuntime=~p~n",[ContainerRuntime]),
        mochijson2:encode({struct , [ {container_name , list_to_binary(ContainerRuntime#container_runtime.name)},
                                      {runtime , list_to_binary(encode(ContainerRuntime#container_runtime.runtime)) }
                                       ] });
                 
        
encode({App,Runtime,AccRuntime} ) when is_record(App , app), is_record(Runtime,runtime) 
        , is_record(AccRuntime,acc_runtime)->
            mochijson2:encode( { struct , [{app ,     list_to_binary(encode(App))},
                                           {runtime , list_to_binary(encode(Runtime))},
                                           {acc_runtime , list_to_binary(encode(AccRuntime))} 
                                       ]});  
encode({App,Runtime,TotalRuntime} ) when is_record(App , app), is_record(Runtime,runtime) 
        , is_record(TotalRuntime,total_runtime)->
            mochijson2:encode( { struct , [{app ,     list_to_binary(encode(App))},
                                           {runtime , list_to_binary(encode(Runtime))},
                                           {total_runtime , list_to_binary(encode(TotalRuntime))} 
                                       ]});  

encode({App,Num}) when is_record(App,app), is_integer(Num)-> 
       mochijson2:encode( { struct , [{app , list_to_binary(encode(App))},
                                         {num ,   Num} 
                                       ]});      

encode({AppName, TotalRuntime}) when is_list(AppName), is_record(TotalRuntime,total_runtime)-> 

       mochijson2:encode( { struct , [{app_name ,   list_to_binary(AppName)},
                                           {total_runtime , list_to_binary(encode(TotalRuntime))}
                                       ]}); 
encode({AppName, TermRuntime}) when is_list(AppName), is_record(TermRuntime,term_runtime)-> 

       mochijson2:encode( { struct , [{app_name ,   list_to_binary(AppName)},
                                           {term_runtime , list_to_binary(encode(TermRuntime))}
                                       ]}); 

encode({Container,L}) when is_record(Container,container), is_list(L)-> 
%%       error_logger:info_msg("encode Container:~p , L:~p~n",[Container,L]),
       mochijson2:encode( { struct , [{container ,   list_to_binary(encode(Container))},
                                           {detail , list_to_binary(encode(L))}
                                       ]});   


         
                
encode({ContainerRuntime , L }=_Msg) when is_record(ContainerRuntime,container_runtime) , is_list(L)->
%%        error_logger:info_msg("Msg=~p~n",[Msg]),
        mochijson2:encode( { struct , [{container_runtime ,     list_to_binary(encode(ContainerRuntime))},
                                           {detail , list_to_binary(encode(L))}
                                       ]});
encode({App , L }) when is_record(App,app) , is_list(L)->
        
        mochijson2:encode( { struct , [{app ,     list_to_binary(encode(App))},
                                           {detail , list_to_binary(encode(L))}
                                       ]});                                        
encode({InstanceRuntime , ContainerRuntime} ) when is_record(ContainerRuntime,container_runtime) 
        , is_record(InstanceRuntime,instance_runtime) ->
       mochijson2:encode( { struct , [{instance_runtime , list_to_binary(encode(InstanceRuntime))},
                                      {container_runtime ,   list_to_binary(encode(ContainerRuntime))}
                                       ]});                                     
                                
                                       
                                       
encode({error,Reason}) when  is_list(Reason)->
            mochijson2:encode({struct , [ {error , list_to_binary(Reason)}] });
            
encode({Container,{error,Reason}}) when is_record(Container,container),  is_list(Reason)->
            mochijson2:encode({struct , [ {container , list_to_binary(encode(Container))},
                                          { error ,    list_to_binary(Reason)}] });
            

encode({Container,Runtime,Num}) when is_record(Container,container) , is_record(Runtime ,runtime),is_integer(Num) ->
          mochijson2:encode( { struct , [{container , list_to_binary(encode(Container))},
                                         {runtime ,   list_to_binary(encode(Runtime))},
                                         {num ,   Num} 
                                       ]}); 
encode({Container,InstanceRuntime,ContainerRuntime})when is_record(Container,container),
is_record(InstanceRuntime , instance_runtime),
        is_record(ContainerRuntime,container_runtime)->
     mochijson2:encode( { struct , [{container ,     list_to_binary(encode(Container))},
                                    {instance_runtime ,     list_to_binary(encode(InstanceRuntime))},
                                    {container_runtime , list_to_binary(encode(ContainerRuntime))}
                                 ]});  

encode([]) ->
  "[]";
encode(L) when is_list(L) ->
%%    error_logger:info_msg("encode Array=~p~n",[L]),
    F = fun (X, Acc) ->
                [$,, encode(X) | Acc]
        end,
    [$, | Acc1] = lists:foldl(F, "[", L),
    lists:reverse([$\] | Acc1]);
encode(T) when is_tuple(T) ->
        error_logger:info_msg("xengine_json:encode tuple ,T=~p~n",[T]),
        mochijson2:encode(list_to_binary(io_lib:format("~p",[T])));                                       
encode(Any) ->
        mochijson2:encode(Any).




     




